using System.Collections.Generic;
using Config;
using Data;
using MoonFramework.Scripts.Tool;
using MoonFramework.Scripts.Tool.System.Setting;
using MoonFramework.Scripts.View.UI;
using MoonFramework.Template;
using MoonFramework.Test;
using Tool;
using Tool.Name;
using UnityEngine;
using UnityEngine.UI;

namespace UI.Map
{
	/// <summary>
	/// UI地图窗口
	/// </summary>
	[UIElement(true, "UI/UI_MapWindow", 3)]
	public class UI_MapWindow : BaseUIWindow
	{
		[SerializeField] private RectTransform content; // 所有地图块，Icon显示的父物体
		private float contentSize;

		[SerializeField] private GameObject mapItemPrefab;	//单张地图在UI中的预制体
		[SerializeField] private GameObject mapIconPrefab;	//单张地图在UI中的预制体
		[SerializeField] private RectTransform playerIcon;	//玩家图标
		
		private readonly Dictionary<Vector2Int, Image> mapImages = new();	//地图图片字典
		private readonly Dictionary<ulong, Image> mapObjectIcons = new();	//所有地图对象物体Icon字典
		private float mapChunkImageSize;    //UI地图块的尺寸
		private int mapChunkSize;			//一块地图块有多少个格子
		private float mapSizeOnWorld;	    //3D地图在世界的坐标
		private Sprite forestSprite;        //森林地块的精灵

		private float minScale;             //最小的放大倍数
		private float maxScale = 10;        //最大的放大倍数

		/// <summary>
		/// 初始化地图
		/// </summary>
		/// <param name="mapSize">一个地图一行或者一列有多少个Image</param>
		/// <param name="mapSizeOnWorld">地图在世界中一行或一列有多大</param>
		/// <param name="forestTexture">森林的贴图</param>
		public void InitMap(float mapSize, int mapBlockSize,float mapSizeOnWorld, Texture2D forestTexture)
		{
			this.mapSizeOnWorld = mapSizeOnWorld;
			this.forestSprite = CreateMapSprite(forestTexture);
			this.mapChunkSize = mapBlockSize;
			//内容尺寸
			contentSize = mapSizeOnWorld * 10;
			content.sizeDelta = Vector2.one * contentSize;
			content.localScale = new Vector3(maxScale, maxScale, 1);
			//一个UI地图块的尺寸
			mapChunkImageSize = contentSize / mapSize;
			minScale = 1050f / contentSize;		//比例系数
		}

		public override void Init()
		{
			base.Init();
			transform.Find("Scroll View").GetComponent<ScrollRect>().onValueChanged.AddListener(UpdatePlayerIconPos);
		}

		private void Update()
		{
			float scroll = Input.GetAxis("Mouse ScrollWheel");
			if (scroll != 0)
			{
				float newScale = Mathf.Clamp(content.localScale.x + scroll, minScale, maxScale);
				content.localScale = new Vector3(newScale, newScale, 0);
			}
		}

		/// <summary>
		/// 更新中心点，为了鼠标缩放的时候，中心点是玩家现在的坐标
		/// </summary>
		public void UpdateCenterPoint(Vector3  playerPosition)
		{
			float x = playerPosition.x / mapSizeOnWorld;
			float y = playerPosition.y / mapSizeOnWorld;
			content.pivot = new Vector2(x, y);
		}

		public void UpdatePlayerIconPos(Vector2 value)
		{
			playerIcon.anchoredPosition3D = content.anchoredPosition3D;
		}

		public void AddMapBlock(Vector2Int BlockIndex, Dictionary<ulong, MapObjectData> mapObjects, Texture2D texture = null)
		{
			RectTransform mapChunkRect = Instantiate(mapItemPrefab, content).GetComponent<RectTransform>();

			//确定地图块的Image的坐标于宽高
			mapChunkRect.anchoredPosition = Vector2.one * BlockIndex * mapChunkImageSize;
			mapChunkRect.sizeDelta = Vector2.one * mapChunkImageSize;

			Image mapBlockImage = mapChunkRect.GetComponent<Image>();
			mapImages.Add(BlockIndex, mapBlockImage);
			//森林的情况
			if (!texture)
			{
				mapBlockImage.type = Image.Type.Tiled;
				//设置贴瓷砖的比例，要在一个Image中显示，这张地图块包含的格子数量
				float ratio = forestSprite.texture.width / mapChunkImageSize; //贴图与Image的比例
				mapBlockImage.pixelsPerUnitMultiplier = mapChunkSize * ratio;//一张地图块有多少个格子
				mapBlockImage.sprite = forestSprite;
			}
			else
				mapBlockImage.sprite = CreateMapSprite(texture);

			//添加物体的Icon
			foreach (var item in mapObjects.Values)
			{
				AddMapObjectIcon(item);
			}
		}

		public void AddMapObjectIcon(MapObjectData mapObjectData)
		{
			MapObjectConfig config = ConfigManager.Instance.GetConfig<MapObjectConfig>(ConfigName.MapObject, mapObjectData.configID);
			if (!config.MapIconSprite || config.IconSize <= 0) return;
			GameObject go = GameObjPoolManager.Instance.Pop<GameObject>(mapIconPrefab.name, mapIconPrefab);
			go.transform.SetParent(content);
			Image iconImage = go.GetComponent<Image>();
			iconImage.sprite = config.MapIconSprite;
			iconImage.transform.localScale = Vector3.one * config.IconSize;
			float x = mapObjectData.position.x * 10;
			float y = mapObjectData.position.z * 10;
			go.GetComponent<RectTransform>().anchoredPosition = new Vector2(x, y);
			mapObjectIcons.Add(mapObjectData.ID, iconImage);	//保存进Icon字典
		}

		private Sprite CreateMapSprite(Texture2D texture)
			=> Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.one * 0.5f);

		/// <summary>
		/// 移除地图对象icon
		/// </summary>
		public void RemoveMapObjectIcon(ulong mapObjectID)
		{
			if (mapObjectIcons.TryGetValue(mapObjectID, out var iconImage))
			{
				//把Icon游戏对象扔回对象池
				iconImage.gameObject.MoonGameObjPushPool();
				mapObjectIcons.Remove(mapObjectID);
			}
		}

		/// <summary>
		/// 回收UI窗口资源
		/// </summary>
		public void ResetWindow()
		{
			foreach (var image in mapObjectIcons.Values)
			{
				image.MoonGameObjPushPool();
			}
			foreach (var image in mapImages.Values)
			{
				Destroy(image.gameObject);
			}
			mapObjectIcons.Clear();
			mapImages.Clear();
		}
	}
}